#include <cerrno>
#include "Event.h"
namespace zg_util{

    Event::Event(bool autoReset): _auto(autoReset), _state(false)
    {
        if (pthread_mutex_init(&_mutex, NULL))
            return;
        if (pthread_cond_init(&_cond, NULL))
            return;
    }


    Event::~Event()
    {
        pthread_cond_destroy(&_cond);
        pthread_mutex_destroy(&_mutex);
    }


    void Event::wait()
    {
        pthread_mutex_lock(&_mutex);
        while (!_state)
        {
            if (pthread_cond_wait(&_cond, &_mutex))
            {
                pthread_mutex_unlock(&_mutex);
                return;
            }
        }
        if (_auto)
            _state = false;
        pthread_mutex_unlock(&_mutex);
    }

/*事件被触发，返回1,超时返回0*/
    bool Event::wait(long milliseconds)
    {
        int rc = 0;
        struct timespec abstime;

        struct timeval tv;
        gettimeofday(&tv, NULL);
        abstime.tv_sec  = tv.tv_sec + milliseconds / 1000;
        abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000;
        if (abstime.tv_nsec >= 1000000000)
        {
            abstime.tv_nsec -= 1000000000;
            abstime.tv_sec++;
        }

        pthread_mutex_lock(&_mutex);
        while (!_state)
        {
            if(rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime)) {
                if (rc == ETIMEDOUT) break;
            }
        }
        if (rc == 0 && _auto) _state = false;
        pthread_mutex_unlock(&_mutex);
        return rc == 0;
    }
}